feat: add W014 case-without-else rule#32
Conversation
There was a problem hiding this comment.
Thanks for your first PR on sql-sop! Quick checks:
pytest -qandruff check .pass locally- Every new rule has both a "fires on bad SQL" test AND a
"does NOT fire on safe SQL" test - Rule IDs (
E001,W001, …) are public API — don't renumber
or rename existing ones without the deprecation process in
GOVERNANCE.md CHANGELOG.md[Unreleased]entry for any user-facing change
First-PR-wins on the linked issue applies for 7 days. The
maintainer will review within 14 days of your last response.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Thanks @hellozzm! Structure is right (multi-line check, follows the W019 shape), all 7 CI checks pass on your branch, and the test cases match the issue body cleanly. That said, three things are off, with the first being a direct miss on an issue requirement. Issue body required nested-CASE detection. Currently broken. Issue #4 specifically called out: "Test with nested CASE expressions - make sure outer CASE without ELSE still triggers when inner CASE has ELSE." The rule fails exactly that case: SELECT CASE
WHEN x THEN CASE WHEN y THEN 1 ELSE 2 END
WHEN z THEN 3
END FROM t; |
c54c6f7 to
d9d2fa8
Compare
Warn on CASE expressions that lack an ELSE branch.\nUnmatched rows silently return NULL which is often unintended.\n\nCloses Pawansingh3889#4
d9d2fa8 to
ea7fa59
Compare
|
Took this over the line. Rebased on main (which now has W015 from #33), reworked the rule into a depth-aware token walk so each CASE/END block is judged independently — the nested example from issue #4 now fires correctly, since the outer block tracks its own ELSE count. Standalone END (T-SQL BEGIN ... END) is ignored when no matching CASE is on the stack. Added two regression tests: outer-CASE-without-ELSE-while-inner-has-ELSE, and a BEGIN/END block that should stay quiet. The original passing/failing tests still pass. CHANGELOG / README / key-numbers bumped to 42/27. Squashing once CI settles. Thanks @hellozzm for the rule, the bones were right and the nesting fix was a small lift on top. |
Summary
Implements rule W014 which warns on
CASE ... ENDexpressions that lack anELSEbranch. Unmatched rows silently return NULL, which is often unintended.Changes
CaseWithoutElserule class insql_guard/rules/warnings.pysql_guard/rules/__init__.pytests/fixtures/warnings.sqltests/test_rules.pyTest plan
Closes #4
Checklist
ruff check .passes (N/A - no ruff installed in CI)pytest -qpasses (36/36)